import { defineStore } from 'pinia';
import PandasNFTJson from "../interact/PandasNFT.json";
import TreasureTokenJson from "../interact/TreasureToken.json";
import PandasMarketJson from "../interact/PandasMarket.json";
import PandasCollectionJson from "../interact/PandasCollection.json";
import { ethers } from "ethers";
import { ElMessage, ElNotification } from 'element-plus';
import { shallowRef } from 'vue'; // ✅ 使用 shallowRef 避免 Proxy 问题

export const useWalletStore = defineStore('wallet', {
  state: () => ({
    walletAddress: '', // 用户钱包地址
    balance: '0',
    provider: shallowRef(null), // Web3 提供者
    signer: shallowRef(null),  // Web3 签名者 
    contract: shallowRef(null), // 合约实例
    tokenContract: shallowRef(null), // ERC20 合约实例
    marketContract: shallowRef(null), // Market 合约实例
    collectionContract: shallowRef(null), // Collection 合约实例
    isConnected: false, // 是否已连接
    connecting: false, // 是否正在连接
    // 保存事件处理函数的引用 - 不再需要这个
  }),
  
  getters: {
    
  },
  
  actions: {
    async connectWallet() {
      if (!window.ethereum) {
        ElMessage.warning('请安装MetaMask或其他以太坊钱包扩展');
        return;
      }
      
      // 如果正在连接，则不要重复操作
      if (this.connecting) return;
      
      try {
        this.connecting = true;
        
        // 请求账户access
        const accounts = await window.ethereum.request({ 
          method: 'eth_requestAccounts' 
        });
        
        if (!accounts || accounts.length === 0) {
          throw new Error('未能获取钱包账户');
        }
        
        // 设置provider和signer
        const provider = new ethers.providers.Web3Provider(window.ethereum, "any");
        const signer = provider.getSigner();
        // 获取当前用户地址
        let userAddress = await signer.getAddress();
        console.log("当前调用合约的钱包地址:", userAddress);
        console.log("provider和signer获取完毕！");
        
        // 获取钱包地址
        const walletAddress = accounts[0];
        console.log("钱包地址为：", walletAddress);
        
         // 初始化合约
        const contract = new ethers.Contract(
          PandasNFTJson.address,
          PandasNFTJson.abi,
          signer
        );
        const tokenContract = new ethers.Contract(
          TreasureTokenJson.address,
          TreasureTokenJson.abi,
          signer
        );
        const marketContract = new ethers.Contract(
          PandasMarketJson.address,
          PandasMarketJson.abi,
          signer
        );
        const collectionContract = new ethers.Contract(
          PandasCollectionJson.address,
          PandasCollectionJson.abi,
          signer
        );
        const network = await provider.getNetwork();
        console.log("当前网络:", network);
        console.log("合约连接成功，Pandas合约地址为：", contract.address);
        console.log("Pandas合约方法为：", contract.functions);
        console.log("合约连接成功，Token合约地址为：", tokenContract.address);
        console.log("Token合约方法为：", tokenContract.functions);
        console.log("合约连接成功，Market合约地址为：", marketContract.address);
        console.log("Market合约方法为：", marketContract.functions);
        console.log("合约连接成功，Collection合约地址为：", collectionContract.address);
        console.log("Collection合约方法为：", collectionContract.functions);
        try {
          const pandasName = await contract.name();
          const tokenName = await tokenContract.name();
          console.log(`Pandas合约名称: ${pandasName}\nToken合约名称: ${tokenName}`);
        } catch (error) {
          console.error("获取合约名称失败:", error);
        }
        
        userAddress = walletAddress
        userAddress = ethers.utils.getAddress(userAddress)
        console.log("当前钱包地址为：", userAddress);
        let balance = await contract.balanceOf(userAddress);
        console.log("当前钱包余额为：", balance.toString());

        // 更新状态
        this.provider = provider;
        this.signer = signer;
        this.walletAddress = walletAddress;
        this.isConnected = true;
        this.contract = contract;
        this.tokenContract = tokenContract;
        this.marketContract = marketContract;
        this.collectionContract = collectionContract;
        
        ElNotification({
          title: '钱包连接成功',
          message: `已连接：${walletAddress.slice(0, 6)}...${walletAddress.slice(-4)}`,
          type: 'success'
        });
        
        // 不在这里设置事件监听器，而是使用独立函数
        this.setupEventListeners();
        
      } catch (error) {
        console.error("连接钱包失败:", error);
        ElMessage.error(`连接钱包失败: ${error.message}`);
        this.isConnected = false;
      } finally {
        this.connecting = false;
      }
    },
    
    // 单独处理事件监听器的设置
    setupEventListeners() {
      // 确保我们已经连接了钱包
      if (!this.isConnected || !window.ethereum) return;
      
      // 定义一个本地函数（不使用 .bind(this)）
      const handleAccountsChanged = (accounts) => {
        if (!accounts || accounts.length === 0) {
          ElMessage.warning("钱包已断开连接");
          this.isConnected = false;
          this.walletAddress = '';
        } else {
          // 更新钱包地址
          this.walletAddress = accounts[0];
          ElMessage.info(`已切换账户: ${this.walletAddress.slice(0, 6)}...${this.walletAddress.slice(-4)}`);
        }
      };
      
      try {
        // 安全地添加事件监听器
        if (typeof window.ethereum.request === 'function') {
          // 不使用 on/addListener，而是使用直接回调
          // 这是一种更安全的方法，避免使用可能不存在的方法
          console.log("正在设置accountsChanged事件监听器...");
          
          // 移除任何现有的监听器 (使用request接口)
          window.ethereum.request({
            method: 'eth_unsubscribe',
            params: ['accountsChanged']
          }).catch(() => {
            // 忽略错误，可能没有现有订阅
          });
          
          // 使用原生请求添加监听
          window.ethereum.request({
            method: 'eth_subscribe',
            params: ['accountsChanged']
          }).then((subscriptionId) => {
            console.log("成功订阅accountsChanged事件，ID:", subscriptionId);
          }).catch((err) => {
            console.warn("事件订阅失败，使用备用方法:", err);
            
            // 备用方法: 使用轮询检查账户变化
            this.setupAccountPolling();
          });
        } else {
          console.warn('以太坊提供者不支持标准事件订阅，使用轮询');
          // 使用轮询作为备选方案
          this.setupAccountPolling();
        }
      } catch (error) {
        console.warn('设置事件监听器失败，使用轮询方式:', error);
        // 使用轮询作为备选方案
        this.setupAccountPolling();
      }
    },
    
    // 使用轮询监控账户变化
    setupAccountPolling() {
      const checkAccount = async () => {
        if (!this.isConnected) return;
        
        try {
          const accounts = await window.ethereum.request({ 
            method: 'eth_accounts' 
          });
          
          if (!accounts || accounts.length === 0) {
            if (this.walletAddress) {
              ElMessage.warning("钱包已断开连接");
              this.isConnected = false;
              this.walletAddress = '';
            }
          } else if (accounts[0] !== this.walletAddress) {
            // 地址已更改
            this.walletAddress = accounts[0];
            ElMessage.info(`已切换账户: ${this.walletAddress.slice(0, 6)}...${this.walletAddress.slice(-4)}`);
          }
        } catch (error) {
          console.warn("账户轮询错误:", error);
        }
      };
      
      // 每3秒检查一次账户状态
      const intervalId = setInterval(checkAccount, 3000);
      
      // 保存intervalId用于清理
      this._accountCheckInterval = intervalId;
    },
    
    // 清理轮询
    clearAccountPolling() {
      if (this._accountCheckInterval) {
        clearInterval(this._accountCheckInterval);
        this._accountCheckInterval = null;
      }
    },
    
    disconnectWallet() {
      // 清理轮询
      this.clearAccountPolling();
      
      // 清理状态
      this.isConnected = false;
      this.walletAddress = '';
      this.provider = null;
      this.signer = null;
      this.contract = null;
      
      ElMessage.info('已断开钱包连接');
    }
  },
  
  persist: {
    // 持久化配置
  },
});